# -*- coding: utf8 -*-

from plugmgr import plugin
from twisted.words.xish.domish import Element

__all__ = ["stanzas"]

class stanzas(plugin):
    """This class provides methods to create and send stanzas"""
    # TODO: what's about other stanzas?
    requires = ["config", "events"]
    types = ["chat", "groupchat", "normal"]
    def __init__(self, bot):
        self.bot = bot
        self.bot["config"].setdefault("maxMsgLength", "4096", 0, 100)
        self.bot["config"].setdefault("status", "online", 0, 9)
        self.bot["config"].setdefault("status_msg", "o_O", 0, 9)
        self.xpaths = ["//message[@from][@type='%s']" % type for type in self.types]
        self.bot['events'].registerEvent('message')
    def setStatus(self,status=None,msg=None,save=True,to=None):
        ''' Change status. If save is set (default), status and its message is saved in configuration '''
        if status is None: status = self.bot["config"]["status"]
        elif save:         self.bot["config"]["status"] = status
        if msg is None:    msg    = self.bot["config"]["status_msg"]
        elif save:         self.bot["config"]["status_msg"] = msg
        
        jids = [to]
        if self.bot.has("muc"):
            jids += self.bot["muc"].rooms.keys()
        for to in jids:
            p = Element(('jabber:client', 'presence'))
            if to: p['to'] = to
            p.addElement('show').addContent(status)
            p.addElement('status').addContent(msg)
            self.bot.stream.send(p)
    def connected(self):
        # send initial presence
        self.setStatus()
        for xpath in self.xpaths:
            self.bot.stream.addObserver(xpath, self.handleMessage)
    def disconnected(self):
        if self.bot.stream:
            for xpath in self.xpaths:
                self.bot.stream.removeObserver(xpath, self.handleMessage)
    def handleMessage(self, message):
        source = message["from"]
        type = message["type"]
        bodies = filter(lambda x: x.name == "body", message.elements())
        if self.bot.has("lang"): lang = self.bot["lang"].detectLanguage(message)
        else: lang = 'en'
        lang = self.bot["config"][(source, "lang")].replace('detect', lang or 'en') # TODO: Crashes when lang is None
        if bodies: body = unicode(bodies[0])
        else: body = ''
        # XEP-0091: Delayed Delivery, it is deprecated but I still receive such stanzas
        delays = [i for i in message.elements() if i.name == 'x' and i.uri == 'jabber:x:delay']
        # XEP-0203: Delayed Delivery
        delays += [i for i in message.elements() if i.name == 'delay' and i.uri == 'urn:xmpp:delay']
        # if message was delayed, don't process it (e.g. MUC history)
        if delays: return
        #print message.toXml()
        #print "LANG=%s" % lang
        #print repr((type, source, body))
        prefix = self.bot["config"][(source, "cmd_prefix")]
        self.bot['events'].raiseEvent('message',source,type,body,lang)
    def sendMessage(self, type, destination, body):
        if not body: return
        # Дополнительные телодвижения для удобства работы с MUC
        if type == 'groupchat':
            destination = destination.split('/')
            try:               nick = '/'.join(destination[1:])
            except IndexError: nick = '' # ни к кому не обращаемся
            destination = destination[0]
            if nick: body = '%s: %s'%(nick,body)
        maxlength = int(self.bot["config"][(destination, "maxMsgLength")])
        stanza = Element(('jabber:client', 'message'))
        stanza['to'] = destination
        stanza['type'] = type
        stanza.addElement('body').addContent(body[:maxlength])
        self.bot.stream.send(stanza)

